package com.web709.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.web709.common.R;
import com.web709.entity.User;
import com.web709.service.UserService;
import com.web709.util.JwtUtils;
import com.web709.util.SMSUtils;
import com.web709.util.ValidateCodeUtils;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;


@RestController
@RequestMapping("/user")
@Slf4j
@Api(tags = "用户管理接口")
public class UserController {

    /**
     * 分页查询用户列表
     */
    @GetMapping("/page")
    @ApiOperation(value = "分页查询用户列表", notes = "支持按姓名、手机号、性别、年龄、地址和创建时间筛选")
    public R<Page<User>> page(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) String sex,
            @RequestParam(required = false) Integer age,
            @RequestParam(required = false) String address,
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime) {
        
        Page<User> pageInfo = new Page<>(page, size);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        queryWrapper.like(StringUtils.isNotEmpty(name), User::getName, name)
                .like(StringUtils.isNotEmpty(phone), User::getPhone, phone)
                .eq(StringUtils.isNotEmpty(sex), User::getSex, sex)
                .eq(age != null, User::getAge, age)
                .like(StringUtils.isNotEmpty(address), User::getAddress, address)
                .ge(StringUtils.isNotEmpty(startTime), User::getCreateTime, startTime)
                .le(StringUtils.isNotEmpty(endTime), User::getCreateTime, endTime)
                .orderByDesc(User::getCreateTime);

        userService.page(pageInfo, queryWrapper);
        return R.success(pageInfo);
    }

    /**
     * 新增用户
     */
    @PostMapping
    @ApiOperation(value = "新增用户", notes = "新增用户信息")
    public R<String> save(@RequestBody User user) {
        // 验证手机号格式
        if (!user.getPhone().matches("^1[3-9]\\d{9}$")) {
            return R.error("手机号格式不正确");
        }
        
        // 验证身份证号格式（如果提供了身份证号）
        if (StringUtils.isNotEmpty(user.getIdNumber()) && 
            !user.getIdNumber().matches("(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)")) {
            return R.error("身份证号格式不正确");
        }

        // 检查手机号是否已存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, user.getPhone());
        if (userService.count(queryWrapper) > 0) {
            return R.error("该手机号已被注册");
        }

        user.setStatus(1); // 设置状态为正常
        userService.save(user);
        return R.success("新增用户成功");
    }

    /**
     * 删除用户
     */
    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除用户", notes = "根据id删除用户信息")
    public R<String> delete(@PathVariable Integer id) {
        if (userService.removeById(id)) {
            return R.success("删除成功");
        }
        return R.error("删除失败");
    }

    @Autowired
    private UserService userService;

    @Autowired
    private SMSUtils smsUtils;

    /**
     * 更新用户信息
     */
    @PutMapping("/{id}")
    @ApiOperation(value = "更新用户信息", notes = "根据id更新用户信息")
    public R<String> update(@PathVariable Integer id, @RequestBody User user) {
        return updateUserInfo(id, user);
    }

    /**
     * 更新用户信息（新接口）
     */
    @PutMapping("/update/{id}")
    @ApiOperation(value = "更新用户信息（新接口）", notes = "根据id更新用户信息，提供额外的验证")
    public R<String> updateUserInfo(@PathVariable Integer id, @RequestBody User user) {
        // 验证用户是否存在
        User existingUser = userService.getById(id);
        if (existingUser == null) {
            return R.error("用户不存在");
        }

        // 验证手机号格式
        if (StringUtils.isNotEmpty(user.getPhone()) && !user.getPhone().matches("^1[3-9]\\d{9}$")) {
            return R.error("手机号格式不正确");
        }
        
        // 如果修改了手机号，检查新手机号是否已被其他用户使用
        if (StringUtils.isNotEmpty(user.getPhone()) && !user.getPhone().equals(existingUser.getPhone())) {
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getPhone, user.getPhone());
            if (userService.count(queryWrapper) > 0) {
                return R.error("该手机号已被其他用户使用");
            }
        }

        // 验证身份证号格式（如果提供了身份证号）
        if (StringUtils.isNotEmpty(user.getIdNumber()) && 
            !user.getIdNumber().matches("(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)")) {
            return R.error("身份证号格式不正确");
        }

        // 设置ID确保更新正确的记录
        user.setId(id);
        
        if (userService.updateById(user)) {
            return R.success("更新成功");
        }
        return R.error("更新失败");
    }


    
    /**
     * 统计用户数量
     *
     * @return 用户总数
     */
    @GetMapping("/count")
    @ApiOperation(value = "统计用户数量", notes = "获取系统中的用户总数")
    public R<Long> count() {
        long count = userService.count();
        return R.success(count);
    }


    /**
     * 发送手机短信验证码
     *
     * @param user
     * @param session
     * @return
     */
    @PostMapping("/sendMsg")
    @ApiOperation(value = "发送手机短信验证码", notes = "发送手机短信验证码")
    @ApiImplicitParam(name = "user.phone", value = "用户信息", required = true, dataType = "User")
    public R<String> sendMsg(@RequestBody User user, HttpSession session) {
        //获取手机号
        String phone = user.getPhone();

        if (StringUtils.isNotEmpty(phone)) {
            //生成随机的4位验证码
            String code = ValidateCodeUtils.generateValidateCode(4).toString();
            log.info("Generated verification code={} for phone={}", code, phone);

            try {
                //调用阿里云提供的短信服务API完成发送短信 (Use injected instance)
                smsUtils.sendMessage(phone, code); 

                //需要将生成的验证码保存到Session
                session.setAttribute(phone, code);
                log.info("Verification code saved to session for phone={}", phone);

                return R.success("手机验证码短信发送成功");
            } catch (Exception e) {
                // Catch exceptions from sendMessage and log/return error
                log.error("Failed to send SMS for phone={}: {}", phone, e.getMessage(), e);
                return R.error("短信发送失败: " + e.getMessage());
            }

        } else {
            log.warn("Attempted to send SMS with empty phone number.");
            return R.error("手机号不能为空");
        }
    }

    /**
     * 获取用户详情
     */
    @GetMapping("/{id}")
    @ApiOperation(value = "获取用户详情", notes = "根据id获取用户详细信息")
    public R<User> getById(@PathVariable Integer id) {
        User user = userService.getById(id);
        if (user != null) {
            return R.success(user);
        }
        return R.error("用户不存在");
    }

    @PostMapping("/login")
    @ApiOperation(value = "用户登录", notes = "{\n" +
            "    \"phone\":\"15819291195\",\n" +
            "    \"code\":\"7179\"\n" +
            "}")
    @ApiImplicitParam(name = "map", value = "用户信息", required = true, dataType = "Map")
public R<String> login(@RequestBody Map<String, String> map, HttpSession session) {
    try {
        // 输入验证
        if (!map.containsKey("phone") || !map.containsKey("code")) {
            return R.error("缺少必要参数");
        }

        String phone = map.get("phone");
        String code = map.get("code");

        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
            return R.error("手机号或验证码不能为空");
        }

        log.info("phone={}, code={}", phone, code);

        // 从Session中获取保存的验证码
        Object codeInSession = session.getAttribute(phone);
        log.info("codeInSession={}", codeInSession);

        // 进行验证码的比对
        if (codeInSession != null && code.equals(codeInSession.toString())) {
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getPhone, phone);

            User user = userService.getOne(queryWrapper);
            if (user == null) {
                // 判断当前手机号对应的用户是否为新用户，如果是新用户就自动完成注册
                user = new User();
                user.setPhone(phone);
                user.setStatus(1);
                user.setSex('男'); // 设置默认性别
                userService.save(user);
            }

            Map<String, Object> claims = new HashMap<>();
            claims.put("userId", user.getId());

            if (StringUtils.isEmpty(user.getName())) {
                String ph = user.getPhone();
                user.setName(ph.substring(0, 3) + "****" + ph.substring(7));
                userService.updateById(user); // 更新用户名
            }
            claims.put("username", user.getName());
            claims.put("userAge", user.getAge());
            claims.put("userSex", user.getSex());
            claims.put("avatar", user.getAvatar());
            claims.put("address", user.getAddress());
            claims.put("phone",user.getPhone());
            String jwt = JwtUtils.generateJwt(claims);
            return R.success(jwt);
        } else {
            return R.error("验证码错误");
        }
    } catch (Exception e) {
        log.error("登录失败: {}", e.getMessage(), e);
        return R.error("系统错误，请稍后再试");
    }
}

    //更新用户信息
    @PutMapping
    @ApiOperation(value = "更新用户信息", notes = "更新用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "用户信息", required = true, dataType = "User"),
            @ApiImplicitParam(name = "token", required = false,paramType = "header",dataType = "String")
    })
    public R<String> update(@RequestBody User user, @RequestHeader(required = false) String token) {
        try {
            log.info("更新用户信息，携带的token: {}，用户信息: {}", token, user);
            
            if (token == null) {
                return R.error("未登录，请先登录");
            }
            
            // 解析token获取用户id
            Map<String, Object> claims = JwtUtils.parseJWT(token);
            Integer userId = (Integer) claims.get("userId");
            user.setId(userId);
            
            // 验证手机号格式
            if (StringUtils.isNotEmpty(user.getPhone()) && !user.getPhone().matches("^1[3-9]\\d{9}$")) {
                return R.error("手机号格式不正确");
            }
            
            // 验证身份证号格式（如果提供了身份证号）
            if (StringUtils.isNotEmpty(user.getIdNumber()) && 
                !user.getIdNumber().matches("(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)")) {
                return R.error("身份证号格式不正确");
            }

            // 检查手机号是否已被其他用户使用
            if (StringUtils.isNotEmpty(user.getPhone())) {
                LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(User::getPhone, user.getPhone())
                           .ne(User::getId, userId);
                if (userService.count(queryWrapper) > 0) {
                    return R.error("该手机号已被其他用户使用");
                }
            }
            
            // 获取当前用户信息
            User currentUser = userService.getById(userId);
            if (currentUser == null) {
                return R.error("用户不存在");
            }
            
            // 处理性别字段，将数字或字符串转换为字符

            // 更新用户信息
            if (userService.updateById(user)) {
                return R.success("更新成功");
            } else {
                return R.error("更新失败，请稍后重试");
            }
        } catch (Exception e) {
            log.error("更新用户信息失败: {}", e.getMessage(), e);
            return R.error("系统错误，请稍后重试");
        }
    }
    //获取用户信息
    @GetMapping("/get")
    @ApiOperation(value = "获取用户信息", notes = "获取用户信息")
    @ApiImplicitParam(name = "token", required = false,paramType = "header",dataType = "String")
    public R<User> get(@RequestHeader(required = false) String token) {
        if (token != null) {
            // 解析token获取用户id
            Map<String, Object> claims = JwtUtils.parseJWT(token);
            Integer userId = (Integer) claims.get("userId");
            User user = userService.getById(userId);
            return R.success(user);
        } else {
            return R.error("获取失败");
        }
    }



}
